package com.rainbow.support.xss.handler;
import cn.hutool.core.util.StrUtil;
import com.rainbow.support.xss.properties.XssProperties;
import com.rainbow.support.xss.warpper.XssRequestWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * XSS过滤
 * @author rainbow
 */
@Slf4j
@RequiredArgsConstructor
public class XssHandlerFilter extends OncePerRequestFilter {

	/**
	 * Xss 防注入配置
	 */
	private final XssProperties xssProperties;

	/**
	 * AntPath规则匹配器
	 */
	private static final AntPathMatcher MATCHER = new AntPathMatcher();

	@Override
	protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
		// 关闭直接跳过
		if (!xssProperties.isEnabled()) {
			return true;
		}
		// 请求方法检查
		if (!StrUtil.equalsAnyIgnoreCase(request.getMethod(), xssProperties.getIncludeHttpMethods().toArray(new String[]{}))) {
			return true;
		}
		// 请求路径检查
		String requestUri = request.getRequestURI();
		// 此路径是否不需要处理
		for (String exclude : xssProperties.getExcludePaths()) {
			if (MATCHER.match(exclude, requestUri)) {
				return true;
			}
		}
		// 路径是否包含
		for (String include : xssProperties.getIncludePaths()) {
			if (MATCHER.match(include, requestUri)) {
				return false;
			}
		}
		return false;
	}

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain) throws ServletException, IOException {
		filterChain.doFilter(new XssRequestWrapper(request), response);
	}



}